package main

import (
	"context"
	"errors"
	"fmt"
	"golang.org/x/sync/errgroup"
	"math/rand"
	"os"
	"os/signal"
	"syscall"
	"time"
	"week5/slidingwindow"
)

func main() {
	// 创建一个滑窗
	var window slidingwindow.ISlidingWindows
	window = slidingwindow.NewWindowTime()
	// 初始化滑窗的时间长度以及桶数量
	err := window.SetUp(2, 10)
	if err != nil {
		fmt.Println(err)
	}
	err = window.Run()
	if err != nil {
		fmt.Println(err)
	}

	eg, ctx := errgroup.WithContext(context.Background())

	// 监听系统关闭信号
	var waiter = make(chan os.Signal, 1) // 按文档指示，至少设置1的缓冲
	signal.Notify(waiter, syscall.SIGTERM, syscall.SIGINT)

	// 模拟请求1
	eg.Go(func() error {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("1退出了")
				return nil
			default:
				err := window.Event()
				if err != nil {
					return err
				}
				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
			}
		}
	})

	// 模拟请求2
	eg.Go(func() error {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("2退出了")
				return nil
			default:
				err := window.Event()
				if err != nil {
					return err
				}
				time.Sleep(time.Millisecond * time.Duration(rand.Intn(100)))
			}
		}
	})

	// 模拟结果遍历
	eg.Go(func() error {
		for {
			select {
			case <-ctx.Done():
				fmt.Println("3退出了")
				return nil
			default:
				fmt.Println(window.Output())
				time.Sleep(time.Second * 1)
			}
		}
	})

	// 等待程序关闭
	eg.Go(func() error {
		select {
		case <-waiter:
			err := window.Stop()
			if err != nil {
				return err
			}
		}
		return errors.New("收到Signal信号")
	})

	if err := eg.Wait(); err != nil {
		fmt.Println("退出原因" + err.Error())
	}
	fmt.Println("程序被关闭")
}
